DROP FUNCTION public."udf_fetchAvailabilities"(integer, integer, text, text);

CREATE OR REPLACE FUNCTION public."udf_fetchAvailabilities"(
	providerid integer,
	providerlocationid integer,
	fromdate text,
	todate text)
    RETURNS TABLE("ProviderAvailabilityId" integer, "ProviderId" integer, "ProviderLocationId" integer, "LocationId" integer, "PracticeName" character varying, "PracticeTIN" character varying, "PracticeLocationName" character varying, "Date" date, "DateNumber" integer, "Day" character varying, "Status" character, "From24HrsTime" text, "To24HrsTime" text, "From12HrsTime" text, "To12HrsTime" text) 
    LANGUAGE 'plpgsql'

    COST 100
    VOLATILE 
    ROWS 1000
AS $BODY$
begin
 return query 
with TotalDates as (
SELECT  generate_series( fromDate::date,toDate::date, '1 day')::date "Dates" ,A."ProviderId",
	A."ProviderLocationId",A."LocationId"
	from "ProviderLocation" A where A."ProviderId"=providerId 
	
	)
,Availability as (
select A."ProviderId",A."ProviderLocationId",A."LocationId",json_array_elements(A."Availability"::json )"Availability" 
	from "ProviderLocation" A where A."ProviderId"=providerId 
	--and case when providerLocationId is null then 1=1 else A."ProviderLocationId"=providerLocationId end 
) 
,AvailData as (
select  A."ProviderId",A."ProviderLocationId",A."LocationId",
	A."Availability"->'day' "Day" ,A."Availability"->'fromTime' "FromTime"
	,A."Availability"->'toTime' "ToTime" from Availability  A
)

,  LeaveAvailability as (
select A."ProviderId",A."LeaveDate",coalesce(A."ProviderLocationId"::text,
 (select string_agg(D."ProviderLocationId"::text,',')  "ProviderLocationId"  from "ProviderLocation" D where D."ProviderId"=providerId
  --and case when providerLocationId is null then 1=1 else D."ProviderLocationId"=providerLocationId end 
 )
 )"ProviderLocationId" from "ProviderLeave" A where A."ProviderId"=providerId 
	--and case when providerLocationId is null then 1=1 else A."ProviderLocationId"=providerLocationId end 
	
) 
,LeaveData as (
select A."ProviderId",A."LeaveDate",regexp_split_to_table(A."ProviderLocationId",',') ::int  "ProviderLocationId"  
	from LeaveAvailability A 
)

,FinalData as (
select distinct C."LeaveDate", A."Dates" "Date", A."ProviderId",A."ProviderLocationId",A."LocationId",extract(ISODOW from "Dates")"DateNo", CASE  
         WHEN extract(ISODOW from "Dates") =1 THEN 'Monday'
         WHEN extract(ISODOW from "Dates") =2 THEN 'Tuesday'
         WHEN extract(ISODOW from "Dates")=3 THEN 'Wednesday'
         WHEN extract(ISODOW from "Dates")=4 THEN 'Thursday'
         WHEN extract(ISODOW from "Dates")=5 THEN 'Friday'
         WHEN extract(ISODOW from "Dates")=6 THEN 'Saturday'
         WHEN extract(ISODOW from "Dates")=7 THEN 'Sunday' end "Day" ,
case when C."LeaveDate" is not null then 'L' when B."Day" is not null then 'A'  else null end "Status" 
,case when C."LeaveDate" is not null then null else  replace (coalesce(B."FromTime"::text,null),'"','') end "FromTime", 
case when C."LeaveDate" is not null then null else 	replace (coalesce(B."ToTime"::text,null),'"','') end "ToTime"
from TotalDates A
left join AvailData B on B."Day"::text::int = extract(ISODOW from A."Dates") and A."ProviderId"=A."ProviderId" and A."ProviderLocationId"=B."ProviderLocationId" 
	and A."LocationId"=B."LocationId"
left join LeaveData C on C."LeaveDate"::date =A."Dates" and A."ProviderLocationId"=C."ProviderLocationId"

) 

select row_number() over()::int "ProviderAvailabilityId",A."ProviderId",A."ProviderLocationId",B."LocationId",
P."FullName" "PracticeName",P."TIN" ,B."Name" "PracticeLocationName"
,A."Date",A."DateNo"::int,A."Day"::text::character varying(10),A."Status"::char, A."FromTime", A."ToTime",
to_char(to_timestamp( A."FromTime", 'HH24:MI'), 'HH12:MI AM') ::text "From12HrsTime" , 
to_char(to_timestamp( A."ToTime", 'HH24:MI'), 'HH12:MI AM') ::text "To12HrsTime"
from FinalData  A	       
join "Location" B on A."LocationId"=B."LocationId" 
join "Practice" P on P."PracticeId"=B."PracticeId"
where case when providerLocationId is null then 1=1 else A."ProviderLocationId"=providerLocationId end 
order by A."Date"
--where "Date"='2020-05-03'::date
--SELECT  TO_TIMESTAMP('20:00', 'HH12:MI:AM')::TIME to_char
-- select to_char('20:00'::timestamp, 'HH12:MI AM')
;
--select::timestamp
--select to_char(to_timestamp( '20:00', 'HH24:MI'), 'HH12:MI AM')
end

$BODY$;

----------------------------


DROP FUNCTION public."udf_fetchAvailableDates"(integer);
CREATE OR REPLACE FUNCTION public."udf_fetchAvailableDates"(
	providerid integer)
    RETURNS TABLE("Date" date, "DateNumber" integer, "DayName" character varying, "Status" character) 
    LANGUAGE 'plpgsql'

    COST 100
    VOLATILE 
    ROWS 1000
AS $BODY$
begin
return query
with TotalDates as (
SELECT DISTINCT generate_series( now()::date,now()::date+ interval '12' month, '1 day')::date "Dates" ,
	A."ProviderId",A."ProviderLocationId",A."LocationId"
from "ProviderLocation" A 
JOIN "Location" PL ON A."LocationId" = PL."LocationId" AND PL."Active" = TRUE
JOIN "Practice" P ON P."PracticeId" = PL."PracticeId" AND P."Active" = TRUE
where A."ProviderId"=providerid AND A."Active" IS TRUE

)
,Availability as (
select A."ProviderId",A."ProviderLocationId",A."LocationId",json_array_elements(A."Availability"::json )"Availability"
from "ProviderLocation" A 
JOIN "Location" PL ON A."LocationId" = PL."LocationId" AND PL."Active" = TRUE
JOIN "Practice" P ON P."PracticeId" = PL."PracticeId" AND P."Active" = TRUE
	where A."ProviderId"=providerid AND A."Active" IS TRUE 
	--and case when providerLocationId is null then 1=1 else A."ProviderLocationId"=providerLocationId end
)
,Avail as (
select A."ProviderId",A."ProviderLocationId",A."LocationId",A."Availability"->'day' "Day" ,
	A."Availability"->'slots' "Slots"
from Availability A
)

, LeaveAvailability as (
select A."ProviderId",A."LeaveDate",coalesce(A."ProviderLocationId"::text,
(
	select string_agg(D."ProviderLocationId"::text,',') "ProviderLocationId" from "ProviderLocation" D where D."ProviderId"= providerid
))
	"ProviderLocationId" from "ProviderLeave" A where A."ProviderId"=providerid
)
,LeaveData as (
select A."ProviderId",A."LeaveDate",regexp_split_to_table(A."ProviderLocationId",',') ::int "ProviderLocationId" 
	from LeaveAvailability A
)

,FinalData as (
select DISTINCT C."LeaveDate", A."Dates" "Date", A."ProviderId",A."ProviderLocationId",
	A."LocationId",extract(ISODOW from "Dates")"DateNo", CASE
WHEN extract(ISODOW from "Dates") =1 THEN 'Monday'
WHEN extract(ISODOW from "Dates") =2 THEN 'Tuesday'
WHEN extract(ISODOW from "Dates")=3 THEN 'Wednesday'
WHEN extract(ISODOW from "Dates")=4 THEN 'Thursday'
WHEN extract(ISODOW from "Dates")=5 THEN 'Friday'
WHEN extract(ISODOW from "Dates")=6 THEN 'Saturday'
WHEN extract(ISODOW from "Dates")=7 THEN 'Sunday' end "Day" ,
case when C."LeaveDate" is not null then 'L' when B."Day" is not null then 'A' else '' end "Status"
from TotalDates A
left join Avail B on B."Day"::text::int = extract(ISODOW from A."Dates") and A."ProviderId"=A."ProviderId" and A."ProviderLocationId"=B."ProviderLocationId"
and A."LocationId"=B."LocationId"
left join LeaveData C on C."LeaveDate"::date =A."Dates" and A."ProviderLocationId"=C."ProviderLocationId"

)

select DISTINCT A."Date",A."DateNo"::int,A."Day"::text::character varying(10),A."Status"::char
from FinalData A
order by A."Date";
end

$BODY$;